<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>生命周期</title>
</head>

<body>
  <div id="app">
    <div @click="fn">{{msg}}</div>
  </div>

  <script src="../node_modules/vue/dist/vue.js"></script>
  <script>
    // 生命周期：
    // vue的实例具有生命周期，vue的实例在生成的时候，会经历一系列的初始化的过程；数据的监听，编译模板，实例挂载DOM元素，或者数据更新导致DOM更新，在执行的过程中，会运行一些叫做生命周期的钩子函数，在Vue实例生命周期中特定的时间点执行的函数称为生命周期的钩子函数；

    // 如果我们需要在某个生命周期处理一些事情，我们可以把这些事情写在钩子函数中；等到vue的实例生命周期到这个阶段就会执行这个钩子，而我们要做的事情也就得以处理了
    // 生命周期的钩子函数不能人为的控制其执行的顺序；

    let vm = new Vue({
      data: {
        msg: 'hello'                                      
      },
      methods: {
        fn() { console.log(11111) }
      },
      beforeCreate() {
        // 在实例初始化之后，数据观测 (data observer) 和watch配置之前被调用。
        console.log(1);
        console.log(this.msg);
        console.log(this.$el); // this.$el 是根DOM元素
      },
      created() {
        // 在实例创建完成后被立即调用。在这一步，实例已完成数据观测、属性和方法的运算、watch/event 事件回调
        // 但是在现阶段还没有开始挂载，即还没挂载到根DOM元素上，所以 this.$el 属性不可见
        console.log(2);
        console.log(this.msg);
        console.log(this.$el);
      },
      beforeMount() {
        // 在挂载开始之前被调用，创建虚拟DOM（Virtual-DOM）；虚拟DOM不是真实的DOM元素，而是js对象，其中包含了渲染成DOM元素信息；
        console.log(3);
        console.log(this.msg);
        console.log(this.$el);
      },
      mounted() {
        // 把Vue的虚拟DOM挂载到真实的DOM上；
        // 如果要在Vue中获取DOM元素对象，一般在这个钩子中获取
        // 项目中的ajax请求一般会在这里或者created里发送；
        console.log(4);
        console.log(this.msg);
        console.log(this.$el);
      },
      // 只有当数据发生变化时，才会触发这个函数；
      beforeUpdate() {
        console.log(5)
      },
      updated() {
        // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁，在这之后会调用该钩子。
        console.log(6);
      },
      beforeDestroy() {
        // 在vue的实例被销毁之前调用，如果页面中有定时器，我们会在这个钩子中清除定时器；
        console.log(7);
      },
      destroyed() {
        // Vue 实例销毁后调用，实例中的属性也不再是响应式的，watch被移除
        console.log(8);
      }
    });

    vm.$set(vm, 'msg', 'hello world'); // 因为vue的数据都是响应式的，只有修改数据才会触发beforeUpdate和updated钩子


    vm.$mount('#app'); // 当创建实例时不传递el属性，可以手动挂载到DOM节点；

    vm.$destroy(); // 手动销毁实例；

  </script>
</body>

</html>